package com.framework.threadpool;

import com.framework.threadpool.reject.RejectHandler;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

@RequiredArgsConstructor
public class MyThreadPoolExecutor {

    private final int coreSize;

    private final int maxSize;

    private final List<Worker> coreWorkers = new ArrayList<>();

    private final List<Worker> supportWorkers = new ArrayList<>();

    @Getter
    private final BlockingQueue<Runnable> queue;

    private final long time;

    private final TimeUnit timeUnit;
    
    private final RejectHandler rejectHandler;

    /**
     * @Description 提交任务到线程池(非线程安全)
     * @author duanzhizhou
     * @date 2025/4/9
     *
     * @param task
     */
    public void execute(Runnable task) {
        if (task == null) {
            throw new RuntimeException("传入的参数为null");
        }
        if (coreWorkers.size() < coreSize) {
            Worker worker = new Worker(task, true);
            coreWorkers.add(worker);
            worker.getThread().start();
        } else if (!queue.offer(task)) {
            if (coreWorkers.size() + supportWorkers.size() < maxSize) {
                Worker worker = new Worker(task, false);
                supportWorkers.add(worker);
                worker.getThread().start();
            } else {
                rejectHandler.reject(task, this);
            }
        }
    }

    class Worker implements Runnable{

        @Getter
        @Setter
        private Runnable task;

        @Getter
        private final Thread thread;

        private final boolean core;

        public Worker(Runnable task, boolean core) {
            this.task = task;
            thread = new Thread(this);
            this.core = core;
        }

        @Override
        public void run() {
            runWorker(this, core);
        }
        
        public void exit() {
            thread.interrupt();
        }
    }

    private void runWorker(Worker worker, boolean core) {
        if (core) {
            runCoreThread(worker);
        } else {
            runSupportThread(worker);
        }
    }
    
    private void runCoreThread(Worker worker) {
        Runnable task = worker.getTask();
        worker.setTask(null);
        while (true) {
            if (task == null) {
                try {
                    task = queue.take();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            task.run();
            task = null;
        }
    }
    
    private void runSupportThread(Worker worker) {
        Runnable task = worker.getTask();
        worker.setTask(null);
        while (true) {
            if (task == null) {
                try {
                    task = queue.poll(time, timeUnit);
                    if (task == null) {
                        System.out.println("辅助线程退出了");
                        break;
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            task.run();
            task = null;
        }
    }
    
    public void shutdown() {
        // TODO
    }
}
